package top.v5it.japi.plus.support.idcenter;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.ArrayUtil;
import top.v5it.japi.plus.support.idcenter.impl.SnowflakeIdCenter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.function.Supplier;

/**
 * id生成接口
 *
 * @author zhanpu
 * @date 2021/3/14
 */
public interface IdCenter {

    /**
     * 默认方法生成id
     *
     * @return
     */
    long nextId();

    /**
     * 生成id，如果使用{@link SnowflakeIdCenter}
     *
     * @param key
     * @param length
     * @return
     */
    long nextId(String key, int length);

    /**
     * 生成id串，长度为length
     *
     * @param key
     * @param length
     * @return
     */
    String nextIdStr(String key, int length);

    /**
     * 根据前缀生成唯一id串
     *
     * @param prefix
     * @param key
     * @param length
     * @return
     */
    default String nextIdStr(String prefix, String key, int length) {
        return nextIdStr(key, length, () -> prefix, true);
    }

    /**
     * 包含'yyyyMMddHHmmssSSS'开始的唯一id串
     *
     * @param key
     * @param length
     * @return
     */
    default String dateTimeNextIdStr(String key, int length) {
        return nextIdStr(key, length, this::dateTimeStr, true);
    }

    /**
     * 包含'yyyyMMdd'开始的唯一id串
     *
     * @param key
     * @param length
     * @return
     */
    default String dateNextIdStr(String key, int length) {
        return nextIdStr(key, length, this::dateStr, true);
    }

    /**
     * 包含'HHmmss'开始的唯一id串
     *
     * @param key
     * @param length
     * @return
     */
    default String timeNextIdStr(String key, int length) {
        return nextIdStr(key, length, this::timeStr, true);
    }

    /**
     * 生成唯一id串，并在后面拼装附加参数
     *
     * @param key
     * @param length
     * @param params
     * @return
     */
    default String nextIdStr(String key, int length, String... params) {
        return nextIdStr(key, length, () -> appendStr(params));
    }

    /**
     * 生成唯一id串
     *
     * @param key
     * @param length
     * @param supplier
     * @param <T>
     * @return
     */
    default <T extends String> String nextIdStr(String key, int length, Supplier<T> supplier) {
        return nextIdStr(key, length, supplier, false);
    }

    /**
     * 生成唯一id串
     *
     * @param key
     * @param length
     * @param supplier
     * @param isBefore
     * @param <T>
     * @return
     */
    default <T extends String> String nextIdStr(String key, int length, Supplier<T> supplier, boolean isBefore) {
        Objects.requireNonNull(supplier);

        T t = supplier.get();
        return isBefore ? t + nextIdStr(key, length) : nextIdStr(key, length) + t;
    }

    /**
     * 获取'yyyyMMddHHmmssSSS'格式时间
     *
     * @return
     */
    default String dateTimeStr() {
        return LocalDateTime.now(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATETIME_MS_PATTERN));
    }

    /**
     * 获取'yyyyMMdd'格式时间
     *
     * @return
     */
    default String dateStr() {
        return LocalDate.now(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(DatePattern.PURE_DATE_PATTERN));
    }

    /**
     * 获取'HHmmss'格式时间
     *
     * @return
     */
    default String timeStr() {
        return LocalTime.now(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(DatePattern.PURE_TIME_PATTERN));
    }

    /**
     * 拼装附加参数
     *
     * @param params
     * @return
     */
    default String appendStr(String... params) {
        return ArrayUtil.isNotEmpty(params) ? String.join("", params) : "";
    }
}
